package org.kalai.unifypay.servlet;

import java.io.IOException;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.kalai.unifypay.Constant;
import org.kalai.unifypay.SessionManager;
import org.kalai.unifypay.bean.Bizcnf;
import org.kalai.unifypay.bean.Member;
import org.kalai.unifypay.bean.TFBAgentPayReqVO;
import org.kalai.unifypay.bean.Transflow;
import org.kalai.unifypay.tfb.pay.TFBAgentPayService;
import org.kalai.unifypay.tfb.pay.TFBUtils;
import org.kalai.unifypay.util.CommonUtil;
import org.kalai.unifypay.util.DataDao;

import com.alibaba.fastjson.JSON;

/**
 * 天付宝异步通知
 * 
 * @author zsl-2016年10月19日
 *
 */
@WebServlet("/TFBNotify")
public class TFBNotify extends HttpServlet {

   private static final long   serialVersionUID = 1L;

   private static final Logger logger           = Logger.getLogger(TFBNotify.class);

   /**
    * @see HttpServlet#HttpServlet()
    */
   public TFBNotify() {
      super();
      // TODO Auto-generated constructor stub
   }

   /**
    * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
    *      response)
    */
   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      // TODO Auto-generated method stub
   }

   /**
    * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
    *      response)
    */
   protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      TreeMap<String, String> requestMap = new TreeMap<String, String>(CommonUtil.getRequestParams(request, "GBK"));
      String tranxSN = requestMap.get("sp_billno").toString();
      try {
         if (!TFBUtils.verifySign(requestMap, Constant.TFB_MD5_SECRET_KEY, requestMap.get("sign"))) {
            logger.error(String.format("(天付宝)返回信息签名失败:[resultMap=%s]", requestMap));
            throw new RuntimeException("验签失败");
         }
         // 查询订单信息
         Transflow transflow = DataDao.getInstance().getTransflow(tranxSN);
         if (transflow == null)
            throw new RuntimeException("订单查询为空");

         TFBNotify.notifyManage(transflow, requestMap);

      } catch (Exception e) {
         logger.error(String.format("(天付宝)异步通知异常:参数[requestMap=%s],异常详情:%s", requestMap, e));
      } finally {
         logger.info("(天付宝)异步通知成功:" + tranxSN);
         CommonUtil.responseObject(response, "SUCCESS");
      }
   }

   /**
    * 处理异步通知
    * 
    * @param transflow
    * @param params
    * @throws Exception
    */
   public static void notifyManage(Transflow transflow, Map<String, String> params) throws Exception {
      if (transflow == null)
         throw new RuntimeException(String.format("交易订单为空,接收天付宝参数:%s", params));

      /* 支付中的订单才进行处理 */
      if (transflow.getStatus() == 1) {

         /* 查询商户信息是否存在 */
         Member member = DataDao.getInstance().getMember(transflow.getMemberNo());
         if (member == null)
            throw new RuntimeException("商户信息不存在:" + transflow.getMemberNo());

         /* 天付宝收到的交易金额 */
         Double tradeAmount = 0.0;
         if (params.get("tran_amt") != null) {
            tradeAmount = Double.valueOf(params.get("tran_amt"));
         }

         String tranState = params.get("tran_state");// 交易状态
         String notifyType = params.get("notify_type");// 通知类型
         String respCode = params.get("retcode");// 返回状态码
         String respMsg = params.get("retmsg");// 返回信息
         /* 交易成功=通知类型为支付+交易状态为成功 */
         if (notifyType.equals("1") && tranState.equals("1")) {
            respCode = "00";
            respMsg = "支付成功";
         }

         /* 更新交易表 */
         boolean isok = "00".equals(respCode);
         DataDao.getInstance().updateTransflow(transflow.getTranxSN(), "", tradeAmount.longValue(), isok ? 2 : 3, respCode,
               respMsg);

         /* 天付宝D0交易成功后实时代付出去 */
         String bizcode = transflow.getBizcode();
         Bizcnf bizcnf = DataDao.getInstance().getBizcnfByCode(bizcode);
         if (isok && bizcnf.getPattern() == 0) {
            String settNo = CommonUtil.generSettNo();

            boolean rs = DataDao.getInstance().addSettlement(transflow.getTranxSN(), settNo, bizcode, member,
                  transflow.getTransAmt() - transflow.getTransFee(), 1);
            if (rs) {
               TFBAgentPayReqVO agentPayReqVO = new TFBAgentPayReqVO();
               agentPayReqVO.setAcct_id(member.getAcctNo());
               agentPayReqVO.setAcct_name(member.getMemberName());
               agentPayReqVO.setBusiness_type("20101");
               agentPayReqVO.setMemo(transflow.getSubject());
               agentPayReqVO.setSp_serialno(settNo);
               agentPayReqVO.setTran_amt((int) (transflow.getTransAmt() * 100 - transflow.getTransFee() * 100));
               agentPayReqVO.setPay_type(1);

               Map<String, String> TFBdfMap = TFBAgentPayService.agentPay(agentPayReqVO);
               if ("00".equals(TFBdfMap.get("respCode")))
               {
                  logger.info(String.format("(天付宝)代付成功:[tranxSN=%s]-[settNo=%s]-[agentAmt=%s]", transflow.getTranxSN(), settNo,
                        agentPayReqVO.getTran_amt()));
               }
               else
               {
                  logger.error(String.format("天付宝代付失败:[tranxSN=%s]-[agentAmt=%s]-[TFBdfMap=%s]", transflow.getTranxSN(),
                        agentPayReqVO.getTran_amt(),TFBdfMap.toString()));
               }
            }
         }
         // 异步通知账单系统
         CommonUtil.notifyTransFlow(transflow);
         /* 异步通知合作方 */
         String url = transflow.getNotifyUrl();
         String partnerCode = transflow.getPartnerCode();
         String secret = DataDao.getInstance().getPartnerByCode(partnerCode).getPartnerSecret();
         if (url != null && !"".equals(url))
            CommonUtil.notifyMessage(url, partnerCode, secret, transflow.getTranxSN(), transflow.getOrderNo(),
                  transflow.getTransAmt(), respCode, respMsg);

         /* websocket推送消息 */
         Map<String, Object> result = CommonUtil.createRespMap(respCode, respMsg);
         SessionManager.getInstance().broadcast(transflow.getTranxSN(), JSON.toJSONString(result));
      } else {
         throw new RuntimeException(transflow.getTranxSN() + "订单状态异常:status=" + transflow.getStatus());
      }
   }
}
